#include "stdafx.h"
// Copyright (c) 1995-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

// Modif JCV 08/01/91 modifs suite a la deuxieme revue de projet
// et introduction des classes XY, Mat2d.
// Modif DPF 23/06/93 Ajout fonction Coord pour genericite 2d 3d

#include "gp_Vec2d.h"
#include "gp_Ax2d.h"
#include "gp_Trsf2d.h"
#include "gp_XY.h"
#include "gp_Pnt2d.h"
#include "gp.h"

void gp_Pnt2d::Transform (const gp_Trsf2d& T)
{
	if (T.Form () == gp_Identity) { }
	else if (T.Form () == gp_Translation)
	{ coord.Add (T.TranslationPart ()); }
	else if (T.Form () == gp_Scale) {
		coord.Multiply (T.ScaleFactor ());
		coord.Add      (T.TranslationPart ());
	}
	else if (T.Form () == gp_PntMirror) {
		coord.Reverse ();
		coord.Add     (T.TranslationPart ());
	}
	else { T.Transforms(coord); }
}

void gp_Pnt2d::Mirror (const gp_Pnt2d& P)
{
	coord.Reverse ();
	gp_XY XY = P.coord;
	XY.Multiply (2.0);
	coord.Add (XY);
}

gp_Pnt2d gp_Pnt2d::Mirrored (const gp_Pnt2d& P) const
{
	gp_Pnt2d Pres = *this;
	Pres.Mirror (P);
	return Pres;
}

void gp_Pnt2d::Mirror (const gp_Ax2d& A)
{
	gp_Trsf2d T;
	T.SetMirror  (A);
	T.Transforms (coord);
}

gp_Pnt2d gp_Pnt2d::Mirrored (const gp_Ax2d& A) const
{
	gp_Pnt2d P = *this;
	P.Mirror (A);
	return P;
}

 gp_Pnt2d::gp_Pnt2d (const gp_XY& Coordinates) : coord (Coordinates)
{ }

 gp_Pnt2d::gp_Pnt2d (const double Xp,
			   const double Yp) : coord (Xp, Yp)
{ }

 gp_Pnt2d::gp_Pnt2d() { }

 double gp_Pnt2d::Coord(const int Index) const { return coord.Coord(Index); }

 void gp_Pnt2d::SetX  (const double X)
{   coord.SetX (X); }

 void gp_Pnt2d::SetY  (const double Y)
{   coord.SetY (Y); }

 void gp_Pnt2d::SetXY (const gp_XY& Coordinates)
{   coord = Coordinates; }

 void gp_Pnt2d::SetCoord (const double Xp,
				const double Yp)
{  coord.SetCoord (Xp, Yp);}

 void gp_Pnt2d::SetCoord (const int Index,
				const double Xi)
{ coord.SetCoord (Index, Xi); }

 void gp_Pnt2d::Coord (double& Xp,
			     double& Yp) const
{ coord.Coord (Xp, Yp); }

 double gp_Pnt2d::X() const
{ return coord.X(); }

 double gp_Pnt2d::Y() const
{ return coord.Y(); }

 const gp_XY& gp_Pnt2d::XY () const
{ return coord; }

 const gp_XY& gp_Pnt2d::Coord () const
{ return coord; }

  gp_XY& gp_Pnt2d::ChangeCoord ()
{ return coord; }

 bool gp_Pnt2d::IsEqual
(const gp_Pnt2d& Other,
 const double LinearTolerance) const
{ return Distance (Other) <= LinearTolerance; }

 double gp_Pnt2d::Distance (const gp_Pnt2d& Other) const
{
  const gp_XY& XY = Other.coord;
  double X = coord.X() - XY.X();
  double Y = coord.Y() - XY.Y();
  return sqrt (X * X + Y * Y);
}

 double gp_Pnt2d::SquareDistance (const gp_Pnt2d& Other) const
{
  const gp_XY& XY = Other.coord;
  double X = coord.X() - XY.X();
  double Y = coord.Y() - XY.Y();
  return (X * X + Y * Y);
}

 void gp_Pnt2d::Rotate (const gp_Pnt2d& P,
			      const double Ang)
{       
  gp_Trsf2d T;
  T.SetRotation (P, Ang);
  T.Transforms  (coord);
}

 gp_Pnt2d gp_Pnt2d::Rotated (const gp_Pnt2d& P,
				   const double Ang) const
{
  gp_Pnt2d Pres = *this;
  Pres.Rotate (P, Ang);
  return Pres;
}

 void gp_Pnt2d::Scale (const gp_Pnt2d& P,
			     const double S)
{
  gp_XY XY = P.coord;
  XY.Multiply (1.0 - S);
  coord.Multiply (S);
  coord.Add      (XY);
}

 gp_Pnt2d gp_Pnt2d::Scaled (const gp_Pnt2d& P,
				  const double S)  const
{
  gp_Pnt2d Pres = *this;
  Pres.Scale (P, S);
  return Pres;
}

 gp_Pnt2d gp_Pnt2d::Transformed (const gp_Trsf2d& T) const
{
  gp_Pnt2d Pres = *this;
  Pres.Transform (T);
  return Pres;
}

 void gp_Pnt2d::Translate (const gp_Vec2d& V)
{ coord.Add (V.XY()); }

 gp_Pnt2d gp_Pnt2d::Translated (const gp_Vec2d& V) const
{
  gp_Pnt2d P = *this;
  P.coord.Add (V.XY ());
  return P;
}

 void gp_Pnt2d::Translate (const gp_Pnt2d& P1,
				 const gp_Pnt2d& P2)
{
  coord.Add      (P2.coord);
  coord.Subtract (P1.coord);
}               

 gp_Pnt2d gp_Pnt2d::Translated (const gp_Pnt2d& P1,
				      const gp_Pnt2d& P2) const
{
  gp_Pnt2d P = *this;
  P.Translate (P1, P2);
  return P;
}               

